/*
* Portuguese eID Card API Native Wrapper
*
* Written by Fernando Nunes (fernando.nunes@devscope.net)
* Copyright (c) 2010 DevScope Information Systems
*
* This library is free software; you can redistribute it and/or 
* modify it under the terms of the GNU Lesser General Public 
* License as published by the Free Software Foundation; either 
* version 2.1 of the License, or (at your option) any later version. 
* 
* This library is distributed in the hope that it will be useful, 
* but WITHOUT ANY WARRANTY; without even the implied warranty of 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
* Lesser General Public License for more details. 
* 
* You should have received a copy of the GNU Lesser General Public 
* License along with this library; if not, write to the Free Software 
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 
*/

#include "stdafx.h"
#include "pteidlib.h"


long __stdcall EIDPT_Init(
	char *ReaderName)		/**< in: the PCSC reader name (as returned by SCardListReaders()),
									 specify NULL if you want to select the first reader */
{
	return PTEID_Init((char*)ReaderName);
}

long __stdcall EIDPT_Exit(
	unsigned long ulMode)	/**< in: exit mode, either PTEID_EXIT_LEAVE_CARD or PTEID_EXIT_UNPOWER */
{
	return PTEID_Exit(ulMode);
}

long __stdcall EIDPT_GetID(
	PTEID_ID *IDData)		/**< out: the address of a PTEID_ID struct */
{
	return PTEID_GetID(IDData);
}

tCardType __stdcall EIDPT_GetCardType(){
	return PTEID_GetCardType();
}

long __stdcall EIDPT_GetAddress(
	PTEID_ADDR *AddrData)	/**< out: the address of an PTEID_ADDR struct */
{
	return PTEID_GetAddr(AddrData);
}

long __stdcall EIDPT_GetPicture(
	PTEID_PIC *PicData)		/**< out: the address of a PTEID_PIC struct */
{
	return PTEID_GetPic(PicData);
}

long __stdcall EIDPT_GetCertificates(
	PTEID_Certifs *Certifs)	/**< out: the address of a PTEID_Certifs struct */
{
	return PTEID_GetCertificates(Certifs);
}

long __stdcall EIDPT_VerifyPIN(
	unsigned char PinId,	/**< in: the PIN ID, see the PTEID_Pins struct */
	char *Pin,				/**< in: the PIN value, if NULL then the user will be prompted for the PIN */
	long *triesLeft)			/**< out: the remaining PIN tries */
{
	return PTEID_VerifyPIN(PinId, Pin, triesLeft);
}

long __stdcall EIDPT_VerifyPIN_No_Alert(
	unsigned char PinId,	/**< in: the PIN ID, see the PTEID_Pins struct */
	char *Pin,				/**< in: the PIN value, if NULL then the user will be prompted for the PIN */
	long *triesLeft)			/**< out: the remaining PIN tries */
{
	return PTEID_VerifyPIN_No_Alert(PinId, Pin, triesLeft);
}

long __stdcall EIDPT_ChangePIN(
	unsigned char PinId,	/**< in: the PIN ID, see the PTEID_Pins struct */
	char *pszOldPin,		/**< in: the current PIN value, if NULL then the user will be prompted for the PIN */
	char *pszNewPin,		/**< in: the new PIN value, if NULL then the user will be prompted for the PIN */
	long *triesLeft)			/**< out: the remaining PIN tries */
{
	return PTEID_ChangePIN(PinId, pszOldPin, pszNewPin, triesLeft);
}

long __stdcall EIDPT_GetPINs(
	PTEID_Pins* Pins)		/**< out: the address of a PTEID_Pins struct */
{
	//PTEID_Pins cPins = PTEID_Pins();
	//long result = PTEID_GetPINs(&cPins);
	//(*pins) = cPins;
	//return result;
	return PTEID_GetPINs(Pins);
}

long __stdcall EIDPT_GetTokenInfo(
	PTEID_TokenInfo *tokenData)	/**< out: the address of a PTEID_TokenInfo struct */
{
	return PTEID_GetTokenInfo(tokenData);
}

long __stdcall EIDPT_ReadSOD(
	unsigned char *out,         /**< out: the buffer to hold the file contents */
	unsigned long *outlen)		/**< in/out: number of bytes allocated/number of bytes read */
{
	return PTEID_ReadSOD(out, outlen);
}

long __stdcall EIDPT_UnblockPIN(
	unsigned char PinId,	/**< in: the PIN ID, see the PTEID_Pins struct */
	char *pszPuk,			/**< in: the PUK value, if NULL then the user will be prompted for the PUK */
	char *pszNewPin,		/**< in: the new PIN value, if NULL then the user will be prompted for the PIN */
	long *triesLeft)			/**< out: the remaining PUK tries */
{
	return PTEID_UnblockPIN(PinId, pszPuk, pszNewPin, triesLeft);
}

long __stdcall EIDPT_UnblockPIN_Ext(
	unsigned char PinId,	/**< in: the PIN ID, see the PTEID_Pins struct */
	char *pszPuk,			/**< in: the PUK value, if NULL then the user will be prompted for the PUK */
	char *pszNewPin,		/**< in: the new PIN value, if NULL then the user will be prompted for the PIN */
	long *triesLeft,		/**< out: the remaining PUK tries */
	unsigned long ulFlags)	/**< in: flags: 0, UNBLOCK_FLAG_NEW_PIN, UNBLOCK_FLAG_PUK_MERGE or
									UNBLOCK_FLAG_NEW_PIN | UNBLOCK_FLAG_PUK_MERGE */
{
	return PTEID_UnblockPIN_Ext(PinId, pszPuk, pszNewPin, triesLeft, ulFlags);
}

long __stdcall EIDPT_SelectADF(
	unsigned char *adf,		/**< in: the AID of the ADF */
	long adflen)				/**< in: the length */
{
	return PTEID_SelectADF(adf, adflen);
}

long __stdcall EIDPT_ReadFile(
	unsigned char *file,	/**< in: a byte array containing the file path,
								e.g. {0x3F, 0x00, 0x5F, 0x00, 0xEF, 0x02} for the ID file */
	int filelen,			/**< in: file length */
	unsigned char *out,		/**< out: the buffer to hold the file contents */
	unsigned long *outlen,	/**< in/out: number of bytes allocated/number of bytes read */
	unsigned char PinId)		/**< in: the ID of the Address PIN (only needed when reading the Address File) */
{
	return PTEID_ReadFile(file, filelen, out, outlen, PinId);
}

long __stdcall EIDPT_WriteFile(
	unsigned char *file,	/**< in: a byte array containing the file path,
								e.g. {0x3F, 0x00, 0x5F, 0x00, 0xEF, 0x02} for the ID file */
	int filelen,			/**< in: file length */
	unsigned char *in,		/**< in: the data to be written to the file */
	unsigned long inlen,	/**< in: length of the data to be written */
	unsigned char PinId)		/**< in: the ID of the Authentication PIN, see the PTEID_Pins struct */
{
	return PTEID_WriteFile(file, filelen, in, inlen, PinId);
}

long __stdcall EIDPT_IsActivated(
	unsigned long *pulStatus)	/**< out the activation status: 0 if not activate, 1 if activated */
{
	return PTEID_IsActivated(pulStatus);
}

long __stdcall EIDPT_Activate(
	char *pszPin,			/**< in: the value of the Activation PIN */
	unsigned char *pucDate,	/**< in: the current date in DD MM YY YY format in BCD format (4 bytes),
									e.g. {0x17 0x11 0x20 0x06} for the 17th of Nov. 2006) */
	unsigned long ulMode)	/**<in: mode: MODE_ACTIVATE_BLOCK_PIN to block the Activation PIN,
									or to 0 otherwise (this should only to be used for testing). */
{
	return PTEID_Activate(pszPin, pucDate, ulMode);
}

long __stdcall EIDPT_SetSODChecking(
	int bDoCheck)	/**< in: true to turn on SOD checking, false to turn it off */
{
	return PTEID_SetSODChecking(bDoCheck);
}

long __stdcall EIDPT_SetSODCAs(
	PTEID_Certifs *Certifs)	/**< in: the address of a PTEID_Certifs, or NULL */
{
	return PTEID_SetSODCAs(Certifs);
}

long __stdcall EIDPT_GetCardAuthenticationKey(
	PTEID_RSAPublicKey *pCardAuthPubKey)	/**< in: the address of a PTEID_RSAPublicKey struct */
{
	return PTEID_GetCardAuthenticationKey(pCardAuthPubKey);
}

long __stdcall EIDPT_GetCVCRoot(
	PTEID_RSAPublicKey *pCVCRootKey)	/**< in: the address of a PTEID_RSAPublicKey struct */
{
	return PTEID_GetCVCRoot(pCVCRootKey);
}

long __stdcall EIDPT_CVC_Init(
    const unsigned char *pucCert,	/**< in: the CVC as a byte array */
    int iCertLen,					/**< in: the length of ucCert */
    unsigned char *pucChallenge,	/**< out: the challenge to be signed by the CVC private key */
    int iChallengeLen)				/**< in: the length reserved for ucChallenge, must be 128 */
{
	return PTEID_CVC_Init(pucCert, iCertLen, pucChallenge, iChallengeLen);
}

long __stdcall EIDPT_CVC_Authenticate(
    unsigned char *pucSignedChallenge,	/**< in: the challenge that was signed by the
											private key corresponding to the CVC */
    int iSignedChallengeLen)				/**< in: the length of ucSignedChallenge, must be 128 */
{
	return PTEID_CVC_Authenticate(pucSignedChallenge, iSignedChallengeLen);
}

long __stdcall EIDPT_CVC_Init_SM101(
    unsigned char *pucChallenge,	/**< out: the challenge to be signed by the derived symmetric key */
    int iChallengeLen)				/**< in: the length reserved for pucChallenge, must be 48 */
{
	return PTEID_CVC_Init_SM101(pucChallenge, iChallengeLen);
}

long __stdcall EIDPT_CVC_Authenticate_SM101(
	const unsigned char *ifdChallenge,	/**< in:  the challenge that was signed by the derived symmetric key */
	int ifdChallengeLen,				/**< in:  the length of ifdChallenge, must be 48 */
	const char *ifdSerialNr,			/**< in:  the serial number of the terminal */
	int ifdSerialNrLen,					/**< in:  the length of the terminal serial number */
	const char *iccSerialNr,			/**< in:  the serial number of the card */
	int iccSerialNrLen,					/**< in:  the length of the card serial number */
	const unsigned char *keyIfd,		/**< in:  the secret key kIFD generated by the terminal */
	int keyIfdLen,						/**< in:  the length of the secret key kIFD */
	const unsigned char * encKey,		/**< in:  the derived encoding key for mutual authentication */
	unsigned int encKeyLen,				/**< in:  the length of the derived encoding key */
	const unsigned char * macKey,		/**< in:  the derived MAC key for mutual authentication */
	unsigned int macKeyLen,				/**< in:  the length of the derived MAC key */
	unsigned char *ifdChallengeResp,	/**< out: the response from the card to the authentication */
	int * ifdChallengeRespLen)			/**< out: the length of ifdChallengeResponse, must be at least 48 */					
{
	return PTEID_CVC_Authenticate_SM101(ifdChallenge, ifdChallengeLen, ifdSerialNr, ifdSerialNrLen, iccSerialNr, iccSerialNrLen, keyIfd, keyIfdLen, encKey, encKeyLen, macKey, macKeyLen, ifdChallengeResp, ifdChallengeRespLen);
}

long __stdcall EIDPT_CVC_ReadFile(
	unsigned char *file,	/**< in: the path of the file to read (e.g. {0x3F, 0x00, 0x5F, 0x00, 0xEF, 0x05} */
	int filelen,			/**< in: the length file path (e.g. 6) */
    unsigned char *out,		/**< out: the buffer to contain the file contents */
    unsigned long *outlen)	/**< out the number of bytes to read/the number of byte read. */
{
	return PTEID_CVC_ReadFile(file, filelen, out, outlen);
}

long __stdcall EIDPT_CVC_WriteFile(
	unsigned char *file,		/**< in: the path of the file to read (e.g. {0x3F, 0x00, 0x5F, 0x00, 0xEF, 0x05} */
	int filelen,				/**< in: the length file path (e.g. 6) */
	unsigned long ulFileOffset,	/**< in: at which offset in the file to start writing */
    const unsigned char *in,	/**< in: the file contents */
    unsigned long inlen,		/**< in: the number of bytes to write */
    unsigned long ulMode)		/**< in: set to CVC_WRITE_MODE_PAD to pad the file with zeros if
									(ulFileOffset + inlen) is less then the file length */
{
	return PTEID_CVC_WriteFile(file, filelen, ulFileOffset, in, inlen, ulMode);
}

long __stdcall EIDPT_CVC_GetAddr(
	PTEID_ADDR *AddrData)	/**< out: the address of a PTEID_ADDR struct */
{
	return PTEID_CVC_GetAddr(AddrData);
}

long __stdcall EIDPT_CVC_WriteAddr(
	const PTEID_ADDR *AddrData)	/**< in: the address of a PTEID_ADDR struct */
{
	return PTEID_CVC_WriteAddr(AddrData);
}

long __stdcall EIDPT_CVC_WriteSOD(
	unsigned long ulFileOffset,	/**< in: at which offset in the file to start writing */
    const unsigned char *in,	/**< in: the file contents */
    unsigned long inlen,		/**< in: the number of bytes to write */
    unsigned long ulMode)		/**< in: set to CVC_WRITE_MODE_PAD to pad the file with zeros if 
									(ulFileOffset + inlen) is less then the file length */
{
	return PTEID_CVC_WriteSOD(ulFileOffset, in, inlen, ulMode);
}

long __stdcall EIDPT_CVC_R_Init(
	unsigned char *ucG,       /**< out: the G parameter */
	unsigned long *outlenG,   /**< in:out length of G parameter, should be 128 */
	unsigned char *ucP,       /**< out: the P parameter */
	unsigned long *outlenP,   /**< in:out length of P parameter, should be 128 */
	unsigned char *ucQ,       /**< out: the Q parameter */
	unsigned long *outlenQ)    /**< in/out length of Q parameter, should be 20 */
{
	return PTEID_CVC_R_Init(ucG, outlenG, ucP, outlenP, ucQ, outlenQ);
}

long __stdcall EIDPT_CVC_R_DH_Auth(
	const unsigned char *ucKifd,    /**<in: Kifd, sent by the Server */
	unsigned long ulKifdLen,        /**<in: Length of Kifd, should be 128 */
	const unsigned char *pucCert,   /**<in: CVC cert */
	unsigned long ulCertLen,        /**<in: CVC cert length */
	unsigned char *ucKicc,          /**<out: Kicc, to be sent to the server */
	unsigned long *ulKiccLen,       /**<out: Kicc length, should be 128 */
	unsigned char *ucChallenge,     /**<out: challenge, to be sent to the server */
	unsigned long *ulChallengeLen) /**<out: challenge length, should be 128 */
{
	return PTEID_CVC_R_DH_Auth(ucKifd, ulKifdLen, pucCert, ulCertLen, ucKicc, ulKiccLen, ucChallenge, ulChallengeLen);
}

long __stdcall EIDPT_CVC_R_ValidateSignature(
	const unsigned char *pucSignedChallenge,  /**< in: the signed challenge */
	unsigned long ulSignedChallengeLen)     /**< in: the length of the signed challenge, should be 128 */
{
	return PTEID_CVC_R_ValidateSignature(pucSignedChallenge, ulSignedChallengeLen);
}

long __stdcall EIDPT_SendAPDU(
	const unsigned char *ucRequest, /**<in: command APDU */
	unsigned long ulRequestLen,     /**<in: command APDU length */
	unsigned char *ucResponse,      /**<out: response APDU */
	unsigned long *ulResponseLen)  /**<in/out: response APDU length */
{
	return PTEID_SendAPDU(ucRequest, ulRequestLen, ucResponse, ulResponseLen);
}

long __stdcall EIDPT_ChangeAddress(
	const char *csServer,                  /**<in: Address Change Server, format: <name>:<port> */
	const unsigned char *ucServerCaCert,   /**<in: CA cert of the Server (DER encoded) */
	unsigned long ulServerCaCertLen,       /**<in: length of the Server CA cert */
	tProxyInfo *proxyInfo,                 /**<in: proxy info, or NULL if no proxy is needed */
	const char *csSecretCode,              /**<in: the Secret code that the citizen received */
	const char* csProcess)                /**<in: the Process code that the citizen received */
{
	return PTEID_ChangeAddress(csServer, ucServerCaCert, ulServerCaCertLen, proxyInfo, csSecretCode, csProcess);
}

tAddressChangeState __stdcall EIDPT_GetChangeAddressProgress()
{
	return PTEID_GetChangeAddressProgress();
}

void __stdcall EIDPT_SetChangeAddressCallback(void(_USERENTRY * callback)(tAddressChangeState state))
{
	return PTEID_SetChangeAddressCallback(callback);
}

void __stdcall EIDPT_CancelChangeAddress()
{
	return PTEID_CancelChangeAddress();
}

long __stdcall EIDPT_CAP_ChangeCapPin(
	const char *csServer,					/**<in: Address Change Server, format: <name>:<port>. */
	const unsigned char *ucServerCaCert,	/**<in: CA cert of the Server (DER encoded). */
	unsigned long ulServerCaCertLen,		/**<in: length of the Server CA cert. */
	tProxyInfo *proxyInfo,					/**<in: proxy info, or NULL if no proxy is needed. */
	const char *pszOldPin,					/**<in: the current CAP PIN. */
	const char *pszNewPin,					/**<in: the new CAP PIN we want to change to. */
	long *triesLeft)						/**<out: The tries left after an unsuccessful attempt. */
{
	return PTEID_CAP_ChangeCapPin(csServer, ucServerCaCert, ulServerCaCertLen, proxyInfo, pszOldPin, pszNewPin, triesLeft);
}

tCapPinChangeState __stdcall EIDPT_CAP_GetCapPinChangeProgress()
{
	return PTEID_CAP_GetCapPinChangeProgress();
}

void __stdcall EIDPT_CAP_SetCapPinChangeCallback(void(_USERENTRY * callback)(tCapPinChangeState state))
{
	return PTEID_CAP_SetCapPinChangeCallback(callback);
}

void __stdcall EIDPT_CAP_CancelCapPinChange()
{
	return PTEID_CAP_CancelCapPinChange();
}

tWebErrorCode __stdcall EIDPT_GetLastWebErrorCode()
{
	return PTEID_GetLastWebErrorCode();
}

const char * __stdcall EIDPT_GetLastWebErrorMessage()
{
	return PTEID_GetLastWebErrorMessage();
}
